package com.lry.write;

import com.lry.Node;
import com.lry.Resp;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;

@Slf4j
public abstract class AbstractWriteConsistency implements WriteConsistency{

    protected List<CompletableFuture<String>> putAsync(String key, String value, List<Node> nodes) {

        List<CompletableFuture<String>> futures = new ArrayList<>();

        for (Node node : nodes) {
            CompletableFuture future = CompletableFuture.supplyAsync(()-> node.put(key,value));
            futures.add(future);
        }
        return futures;
    }

    protected String putReturn(List<CompletableFuture<String>> futures, int requireSuccessNum){
        LongAdder successNum = new LongAdder();


        for (CompletableFuture<String> future : futures) {
            //多线程防止第一个由于网络问题卡住，获取结果，执行自增
            CompletableFuture.runAsync(() -> {
                try {
                    String result = future.get();
                    if (Resp.OK.getResult().equals(result)) {
                        successNum.increment();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });
        }

        while(successNum.intValue()<requireSuccessNum){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return Resp.OK.getResult();
    }

//    protected String putReturn(List<CompletableFuture<String>> futures, int requireSuccessNum){
//        LongAdder successNum = new LongAdder();
//
//        CountDownLatch cdl = new CountDownLatch(1);
//
//        for (CompletableFuture<String> future : futures) {
//            //多线程防止第一个由于网络问题卡住，获取结果，执行自增
//            CompletableFuture.runAsync(() -> {
//                try {
//                    String result = future.get();
//                    if (Resp.OK.getResult().equals(result)) {
//                        successNum.increment();
//                        if(successNum.intValue()>=requireSuccessNum){
//                            cdl.countDown();
//                        }
//                    }
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                } catch (ExecutionException e) {
//                    e.printStackTrace();
//                }
//            });
//        }
//
//
//        try {
//            cdl.await();
//        } catch (InterruptedException e) {
//            log.info("写数据超时");
//            e.printStackTrace();
//            return Resp.FAIL.getResult();
//        }
//
//        return Resp.OK.getResult();
//    }

}
